﻿using SD.IdentitySystem.IAppService.DTOs.Inputs;
using SD.IdentitySystem.IAppService.DTOs.Outputs;
using SD.IdentitySystem.IAppService.Interfaces;
using SD.Infrastructure.Constants;
using SD.IOC.Core.Mediators;
using SD.Toolkits.Excel;
using SlamDunk.MES.DataDrive.Bussiness.Models.IdentityContext;
using SlamDunk.MES.DataDrive.Common;
using SlamDunk.MES.DataDrive.Common.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SlamDunk.MES.DataDrive.Bussiness.Importers
{
    /// <summary>
    /// 导入身份认证
    /// </summary>
    [DataTag(11, "身份认证数据", "MES身份认证数据", DataDriveConfig.IdentityName, DataDriveConfig.IdentityConnectionStrings)]
    public class ImportIdentity
    {
        #region # 导入信息系统 —— void ImportInfoSystems()
        /// <summary>
        /// 导入信息系统
        /// </summary>
        [DataTag("导入信息系统")]
        public void ImportInfoSystems()
        {
            IAuthorizationContract authorizationContract = ResolveMediator.Resolve<IAuthorizationContract>();
            InfoSystem[] infoSystems = ExcelReader.ReadFile<InfoSystem>(SystemConfig.InitalForIdentityDataPath, "信息系统");

            foreach (InfoSystem infoSystem in infoSystems)
            {
                ApplicationType applicationType = (ApplicationType)Enum.Parse(typeof(ApplicationType), infoSystem.应用程序类型);
                authorizationContract.CreateInfoSystem(infoSystem.信息系统编号, infoSystem.信息系统名称, infoSystem.管理员登录名, applicationType);
            }
        }
        #endregion

        #region # 导入权限 —— void ImportAuthorities()
        /// <summary>
        /// 导入权限
        /// </summary>
        [DataTag("导入权限")]
        public void ImportAuthorities()
        {
            IAuthorizationContract authorizationContract = ResolveMediator.Resolve<IAuthorizationContract>();
            Authority[] authorities = ExcelReader.ReadFile<Authority>(SystemConfig.InitalForIdentityDataPath, "权限");
            var authorityGroups = authorities.GroupBy(x => new
            {
                x.信息系统编号,
                x.应用程序类型
            });

            foreach (var authorityGroup in authorityGroups)
            {
                IList<AuthorityParam> authorityParams = new List<AuthorityParam>();
                foreach (Authority authority in authorityGroup)
                {
                    AuthorityParam authorityParam = new AuthorityParam()
                    {
                        authorityName = authority.权限名称,
                        authorityPath = authority.权限路径
                    };
                    authorityParams.Add(authorityParam);
                }

                ApplicationType applicationType = (ApplicationType)Enum.Parse(typeof(ApplicationType), authorityGroup.Key.应用程序类型);
                authorizationContract.CreateAuthorities(authorityGroup.Key.信息系统编号, applicationType, authorityParams);
            }
        }
        #endregion

        #region # 导入菜单 —— void ImportMenus()
        /// <summary>
        /// 导入菜单
        /// </summary>
        [DataTag("导入菜单")]
        public void ImportMenus()
        {
            IAuthorizationContract authorizationContract = ResolveMediator.Resolve<IAuthorizationContract>();
            Menu[] menus = ExcelReader.ReadFile<Menu>(SystemConfig.InitalForIdentityDataPath, "菜单");

            IEnumerable<IGrouping<string, Menu>> menuGroups = menus.GroupBy(x => x.信息系统编号);
            foreach (IGrouping<string, Menu> menuGroup in menuGroups)
            {
                //获取信息系统根级菜单
                IEnumerable<MenuInfo> menuInfos = authorizationContract.GetMenus(null, menuGroup.Key, null);
                Guid systemMenuId = menuInfos.First().Id;

                IList<Menu> rootMenus = menuGroup.Where(x => string.IsNullOrWhiteSpace(x.上级Id)).ToList();
                this.CreateMenus(authorizationContract, menuGroup.Key, menus, rootMenus, systemMenuId);
            }
        }
        #endregion

        #region # 关联权限到菜单 —— void RelateAuthoritiesToMenus()
        /// <summary>
        /// 关联权限到菜单
        /// </summary>
        [DataTag("关联权限到菜单")]
        public void RelateAuthoritiesToMenus()
        {
            IAuthorizationContract authorizationContract = ResolveMediator.Resolve<IAuthorizationContract>();
            MenuRelatedAuthority[] relatedAuthorities = ExcelReader.ReadFile<MenuRelatedAuthority>(SystemConfig.InitalForIdentityDataPath, "菜单相关权限");

            MenuInfo[] menuInfos = authorizationContract.GetMenus(null, null, null).ToArray();
            AuthorityInfo[] authorityInfos = authorizationContract.GetAuthorities(null, null, null, null, null).ToArray();

            var relatedAuthorityGroups = relatedAuthorities.GroupBy(x => new
            {
                x.信息系统编号,
                x.应用程序类型,
                x.菜单名称
            });
            foreach (var relatedAuthorityGroup in relatedAuthorityGroups)
            {
                ApplicationType applicationType = (ApplicationType)Enum.Parse(typeof(ApplicationType), relatedAuthorityGroup.Key.应用程序类型);
                MenuInfo menuInfo = menuInfos.Single(x => x.InfoSystemNo == relatedAuthorityGroup.Key.信息系统编号 && x.ApplicationType == applicationType && x.Name == relatedAuthorityGroup.Key.菜单名称);

                IList<AuthorityInfo> relatedAuthorityInfos = new List<AuthorityInfo>();
                foreach (MenuRelatedAuthority relatedAuthority in relatedAuthorityGroup)
                {
                    AuthorityInfo authorityInfo = authorityInfos.Single(x => x.ApplicationType == applicationType && x.Name == relatedAuthority.权限名称);
                    relatedAuthorityInfos.Add(authorityInfo);
                }

                IEnumerable<Guid> authorityIds = relatedAuthorityInfos.Select(x => x.Id);
                authorizationContract.RelateAuthoritiesToMenu(menuInfo.Id, authorityIds);
            }
        }
        #endregion

        #region # 导入角色 —— void ImportRoles()
        /// <summary>
        /// 导入角色
        /// </summary>
        [DataTag("导入角色")]
        public void ImportRoles()
        {
            IAuthorizationContract authorizationContract = ResolveMediator.Resolve<IAuthorizationContract>();
            Role[] roles = ExcelReader.ReadFile<Role>(SystemConfig.InitalForIdentityDataPath, "角色");
            foreach (Role role in roles)
            {
                authorizationContract.CreateRole(role.信息系统编号, role.角色名称, role.描述, null);
            }
        }
        #endregion

        #region # 关联权限到角色 —— void RelateAuthoritiesToRoles()
        /// <summary>
        /// 关联权限到角色
        /// </summary>
        [DataTag("关联权限到角色")]
        public void RelateAuthoritiesToRoles()
        {
            IAuthorizationContract authorizationContract = ResolveMediator.Resolve<IAuthorizationContract>();
            RoleRelatedAuthority[] relatedAuthorities = ExcelReader.ReadFile<RoleRelatedAuthority>(SystemConfig.InitalForIdentityDataPath, "角色相关权限");

            RoleInfo[] roleInfos = authorizationContract.GetRoles(null, null, null).ToArray();
            AuthorityInfo[] authorityInfos = authorizationContract.GetAuthorities(null, null, null, null, null).ToArray();

            var relatedAuthorityGroups = relatedAuthorities.GroupBy(x => new
            {
                x.信息系统编号,
                x.角色名称
            });
            foreach (var relatedAuthorityGroup in relatedAuthorityGroups)
            {
                RoleInfo roleInfo = roleInfos.Single(x => x.InfoSystemNo == relatedAuthorityGroup.Key.信息系统编号 && x.Name == relatedAuthorityGroup.Key.角色名称);

                IList<AuthorityInfo> relatedAuthorityInfos = new List<AuthorityInfo>();
                foreach (RoleRelatedAuthority relatedAuthority in relatedAuthorityGroup)
                {
                    ApplicationType applicationType = (ApplicationType)Enum.Parse(typeof(ApplicationType), relatedAuthority.应用程序类型);
                    AuthorityInfo authorityInfo = authorityInfos.Single(x => x.ApplicationType == applicationType && x.Name == relatedAuthority.权限名称);
                    relatedAuthorityInfos.Add(authorityInfo);
                }

                IEnumerable<Guid> authorityIds = relatedAuthorityInfos.Select(x => x.Id);
                authorizationContract.RelateAuthoritiesToRole(roleInfo.Id, authorityIds);
            }
        }
        #endregion

        #region # 导入用户 —— void ImportUsers()
        /// <summary>
        /// 导入用户
        /// </summary>
        [DataTag("导入用户")]
        public void ImportUsers()
        {
            IUserContract userContract = ResolveMediator.Resolve<IUserContract>();
            User[] users = ExcelReader.ReadFile<User>(SystemConfig.InitalForIdentityDataPath, "用户");
            foreach (User user in users)
            {
                userContract.CreateUser(user.用户名, user.真实姓名, user.密码);
            }
        }
        #endregion

        #region # 关联角色到用户 —— void RelateRolesToUsers()
        /// <summary>
        /// 关联角色到用户
        /// </summary>
        [DataTag("关联角色到用户")]
        public void RelateRolesToUsers()
        {
            IUserContract userContract = ResolveMediator.Resolve<IUserContract>();
            IAuthorizationContract authorizationContract = ResolveMediator.Resolve<IAuthorizationContract>();
            UserRelatedRole[] relatedRoles = ExcelReader.ReadFile<UserRelatedRole>(SystemConfig.InitalForIdentityDataPath, "用户相关角色");

            RoleInfo[] roleInfos = authorizationContract.GetRoles(null, null, null).ToArray();
            IEnumerable<IGrouping<string, UserRelatedRole>> relatedRoleGroups = relatedRoles.GroupBy(x => x.用户名);
            foreach (IGrouping<string, UserRelatedRole> relatedRoleGroup in relatedRoleGroups)
            {
                IList<RoleInfo> relatedRoleInfos = new List<RoleInfo>();
                foreach (UserRelatedRole userRelatedRole in relatedRoleGroup)
                {
                    RoleInfo roleInfo = roleInfos.Single(x => x.InfoSystemNo == userRelatedRole.信息系统编号 && x.Name == userRelatedRole.角色名称);
                    relatedRoleInfos.Add(roleInfo);
                }

                IEnumerable<Guid> roleIds = relatedRoleInfos.Select(x => x.Id);
                userContract.RelateRolesToUser(relatedRoleGroup.Key, roleIds);
            }

        }
        #endregion


        //Private

        #region # 创建菜单 —— void CreateMenus(IAuthorizationContract...
        /// <summary>
        /// 创建菜单
        /// </summary>
        private void CreateMenus(IAuthorizationContract authorizationContract, string infoSystemNo, ICollection<Menu> allMenus, ICollection<Menu> menus, Guid parentId)
        {
            foreach (Menu menu in menus)
            {
                ApplicationType applicationType = (ApplicationType)Enum.Parse(typeof(ApplicationType), menu.应用程序类型);

                //创建菜单
                Guid menuId = authorizationContract.CreateMenu(infoSystemNo, applicationType, menu.菜单名称, menu.排序, menu.链接地址, menu.路径, menu.图标, parentId);

                //创建下级菜单
                IList<Menu> subMenus = allMenus.Where(x => x.上级Id == menu.Id).ToList();
                this.CreateMenus(authorizationContract, infoSystemNo, allMenus, subMenus, menuId);
            }
        }
        #endregion
    }
}
